package com.pms.util.baidu;

import com.alibaba.fastjson.JSONObject;
import com.pms.util.Description;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.*;

/**
 * Created by Administrator on 2018/10/22.
 */
public class DataPointAnnotationUtil {
    protected static Logger logger = LoggerFactory.getLogger(DataPointAnnotationUtil.class);
    /**
     * 根据 obj 对象 生成 修改或添加 的参数字符串 eg: title=1234&longitude=101.224
     * @param obj 对象
     */
    public static  List<JSONObject> generateDataPointList(Object obj) {
        if (obj == null){return null;}
        String metricName =null;
        Long timestamp = null;
        DataPointAnnotation metric = obj.getClass().getAnnotation(DataPointAnnotation.class);
        if(metric==null){
            metricName = obj.getClass().getName();
        }
        if(metric!=null){
            metricName = metric.name();
            if(metricName==null||metricName==""){
                metricName = obj.getClass().getName();
            }
        }
        Map<String,Object> fieldMap = new HashMap<String,Object>();
        Map<String,String> fieldTypeMap = new HashMap<String,String>();
        JSONObject tagJson = new JSONObject();
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field f : fields) {
            // 类中的成员变量为private,获取该成员变量的值 必须进行此操作
            f.setAccessible(true);
            // 获取字段的注解
            DataPointAnnotation annotation = f.getAnnotation(DataPointAnnotation.class);
            if(null!=annotation){
                try{
                    Object fvalue = f.get(obj);
                    if(fvalue!=null ) {
                        if(annotation.type()==3){// 标签
                            String tagName = annotation.name();
                            if(StringUtils.isBlank(tagName)){
                                tagName = f.getName();
                            }
                            tagJson.put(tagName,fvalue);
                        }
                        if(annotation.type()==4){// 时间戳
                            String fieldTypeStr = f.getGenericType().toString();
                            if(fieldTypeStr.indexOf("java.util.Date")!=-1){
                                Date date = (Date) fvalue;
                                timestamp = date.getTime();
                            }else{
                                timestamp = (Long)fvalue;
                            }
                        }
                        if(annotation.type()==2){// 2-字段(filed)名
                            String fieldName = annotation.name();
                            if(StringUtils.isBlank(fieldName)){
                                fieldName = f.getName();
                            }
                            fieldMap.put(fieldName,fvalue);
                            String type = "Bytes";// 默认为 1-Long/2-Double/3-String/4-Bytes
                            String fieldTypeStr = f.getGenericType().toString();
                            if(fieldTypeStr.indexOf("Integer")!=-1||fieldTypeStr.indexOf("Long")!=-1
                                 ||fieldTypeStr.indexOf("Byte")!=-1||fieldTypeStr.indexOf("Short")!=-1   ){
                                type = "Long";
                            }
                            if(fieldTypeStr.indexOf("BigDecimal")!=-1||fieldTypeStr.indexOf("Double")!=-1
                                    ||fieldTypeStr.indexOf("Float")!=-1){
                                type = "Double";
                            }
                            if(fieldTypeStr.indexOf("String")!=-1){
                                type = "String";
                            }
                            fieldTypeMap.put(fieldName,type);
                        }
                    }
                }catch (IllegalArgumentException e) {
                    logger.error(obj.getClass()+"解析注解DataPointAnnotation反射获取值异常",e);
                    return null;
                } catch (IllegalAccessException e) {
                    logger.error(obj.getClass()+"解析注解DataPointAnnotation反射获取值异常",e);
                    return null;
                }catch (ClassCastException ex){
                    logger.error(obj.getClass()+"解析注解DataPointAnnotation反射获取值异常",ex);
                    return null;
                }
            }
        }
        if(timestamp==null){
            return null;
        }
        List<JSONObject> dataPointList = new ArrayList<JSONObject>();
        for(Map.Entry<String, Object> entry : fieldMap.entrySet()){
            JSONObject dataPoint = new JSONObject();
            dataPoint.put("metric",metricName); // 表名
            dataPoint.put("timestamp",timestamp);
            dataPoint.put("tags",tagJson);
            dataPoint.put("field",entry.getKey());// 列
            dataPoint.put("value",entry.getValue());// 值
            dataPoint.put("type",fieldTypeMap.get(entry.getKey())==null?3:fieldTypeMap.get(entry.getKey()));
            dataPointList.add(dataPoint);
        }
        return dataPointList;
    }
}
